package com.linewell.encryption.enums;

import com.linewell.encryption.pojo.SMInitInfo;
import com.linewell.encryption.services.SMEncryptionService;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.Objects;

/**
 * 密码机工厂类
 * Company: 南威软件股份有限公司
 *
 * @author wucan
 * @date 2019-03-15
 */
public enum SMFactoryEnum {

    /**
     * JCE-凯特加解密
     */
    JCE("JCE", "凯特", "com.linewell.license.encryption.services.JCESMEncryptionServiceImpl"),
    /**
     * SYSTEM-程序自行加解密
     */
    SYSTEM("SYSTEM", "程序自行加解密", "com.linewell.encryption.services.impl.SystemSMEncryptionServiceImpl"),;

    /**
     * appId 厂家类型
     */
    private final String appId;
    /**
     * appId 厂家名称
     */
    private final String name;
    /**
     * 类名
     */
    private final String className;


    SMFactoryEnum(String appId, String name, String className) {
        this.appId = appId;
        this.name = name;
        this.className = className;
    }

    public String getAppId() {
        return appId;
    }

    public String getName() {
        return name;
    }

    public String getClassName() {
        return className;
    }

    public static SMFactoryEnum getByCode(String appId) {
        for (SMFactoryEnum v : SMFactoryEnum.values()) {
            if (Objects.equals(v.getAppId(), appId)) {
                return v;
            }
        }
        return null;
    }

    /**
     * 加解密实例
     *
     * @param initInfo 加解密初始化对象
     * @return 加密实现类实例
     */
    public static SMEncryptionService getService(SMInitInfo initInfo) throws IllegalAccessException, InstantiationException, ClassNotFoundException, NoSuchMethodException, InvocationTargetException {
        if (Objects.isNull(initInfo)) {
            throw new NullPointerException("SMInitInfo is null");
        }
        SMFactoryEnum factoryEnum = SMFactoryEnum.getByCode(initInfo.getAppId());
        if (Objects.nonNull(factoryEnum)) {
            Class<?> clazz = Class.forName(factoryEnum.getClassName());
            if (Objects.isNull(clazz)) {
                throw new NullPointerException("class is null");
            }
            Constructor c = clazz.getConstructor(SMInitInfo.class);
            return (SMEncryptionService) c.newInstance(initInfo);
        }

        throw new NullPointerException("service is null");

    }


}
